package gui.cen.south;

import core.utils.Utils;
import gui.utils.Borders;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.LinkedList;
import javax.swing.JPanel;
import gui.utils.Para;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class HeatMap extends JPanel{
    private int noOfBuckets = 101;
    private LinkedList <Color> colors = null;

    public HeatMap(){
        super();
        this.setBackground(new Color(102, 102, 102));
        if(colors==null){colors = Utils.getColors((int)noOfBuckets);}
        this.repaint();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawAxis(g);
    }

    public void updatePlots(){bg = null;this.repaint();}

    private Graphics2D bg = null;
    private Image offScreen = null;

    //120 is just a start value not used
    static int space = 4;
    public static int HEIGHT_OF_HEATMAP = (Borders.SEQCHARHEIGHT + space) * 6;

    private void drawAxis(Graphics g){
        try{
            double [] data_Coverage = Para.HEATMAP_DATA.getCov();
            double [] data_Entropy = Para.HEATMAP_DATA.getEnt();
            char [] consensus = Para.HEATMAP_DATA.getCon();

            int space = 4;
            final int imageHeight = (Borders.SEQCHARHEIGHT + space) * 6;
            HEIGHT_OF_HEATMAP = imageHeight;
            final int imageWidth = this.getWidth();
            int noOfCharactersToShow = (imageWidth / Borders.SEQ_CHAR_WIDTH);
            this.setLayout(new FlowLayout(){public Dimension preferredLayoutSize(Container cont) {return (new Dimension(imageWidth, imageHeight));}});
            if(Para.HEATMAP_DATA!=null) {
                String template = "";
                template = Para.PB.getRef().getDNA();
                offScreen = this.createImage(imageWidth, imageHeight);
                bg = (Graphics2D)offScreen.getGraphics();
                bg.setColor(new Color(102, 102, 102));
                bg.fillRect(0, 0, imageWidth, imageHeight);
                bg.setFont(Borders.getFont(Borders.SEQFONT));
                
                int yLocation = 0;
                int templateIndex = Para.TPOS;
                for(int s=0; s<noOfCharactersToShow && templateIndex < template.length(); s++){
                    yLocation = Borders.SEQCHARHEIGHT;
                    if(s==0){
                        bg.setColor(new Color(178, 178, 178));
                        bg.drawString("REFERENCE:", (s * Borders.SEQ_CHAR_WIDTH), yLocation);
                    }
                    else if(s>15){
                        //REFERENCE
                        bg.setColor(new Color(178, 178, 178));
                        bg.drawString(consensus[templateIndex]+"", (s * Borders.SEQ_CHAR_WIDTH), yLocation);
                    }

                    yLocation = yLocation + (Borders.SEQCHARHEIGHT - space);
                    if(s==0){
                        bg.setColor(new Color(178, 178, 178));
                        bg.drawString("COVER:", (s * Borders.SEQ_CHAR_WIDTH), yLocation + 10);
                    }
                    else if(s>15){
                        //coverage
                        bg.setColor(colors.get((int)data_Coverage[templateIndex]));
                        bg.fill(new Rectangle(s * Borders.SEQ_CHAR_WIDTH, yLocation, Borders.SEQ_CHAR_WIDTH-1, Borders.SEQCHARHEIGHT));
                    }

                    yLocation = yLocation + (Borders.SEQCHARHEIGHT + space);
                    if(s==0){
                        bg.setColor(new Color(178, 178, 178));
                        bg.drawString("ENTROPY:", (s * Borders.SEQ_CHAR_WIDTH), yLocation + 10);
                    }
                    else if(s>15){
                        //entropy
                        bg.setColor(colors.get((int)data_Entropy[templateIndex]));
                        bg.fill(new Rectangle(s * Borders.SEQ_CHAR_WIDTH, yLocation, Borders.SEQ_CHAR_WIDTH-1, Borders.SEQCHARHEIGHT));
                    }

                    if(s == (Para.TABLE_ROW)){bg.setColor(Color.YELLOW);}
                    else{ bg.setColor(new Color(178, 178, 178));}
                    yLocation = yLocation + (Borders.SEQCHARHEIGHT + 14);
                    if(templateIndex%10==0){bg.drawString(templateIndex+"", s * Borders.SEQ_CHAR_WIDTH, yLocation);}

                    templateIndex++;
                }
                
                //draw color scale
                int xLocation = 12;
                yLocation = yLocation + 10;
                for(int c=0; c<colors.size(); c++){
                    bg.setColor(colors.get(c));
                    bg.fill(new java.awt.Rectangle(xLocation, yLocation + 10,  2, 5));
                    xLocation = xLocation + 3;
                }
                bg.setColor(Color.WHITE);
                bg.drawString("0", 0, yLocation + 16);
                bg.drawString("100%", 318, yLocation + 16);
                bg.setColor(new Color(178, 178, 178));
                bg.drawString("(No. of reads mapped: "+Para.PB.getSize()+")", 360, yLocation + 16);
            }
            g.drawImage(offScreen, 0, 0, imageWidth, imageHeight, this);
        }
        catch(Exception e){}
    }
}